package com.nlp.solve.issue_g;

/*中国与各个东盟成员国在各个学科领域中有哪些核心作者（前30个）
和//重要单位（前10个），分中国（广东）和东盟各个国家分开统计
*/

import com.alibaba.fastjson.JSONObject;
import com.nlp.model.Article;
import com.nlp.solve.Main;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/*
1、中国与各个东盟成员国在各个学科领域中有哪些核心作者
（前30个）和重要单位（前10个），分中国（广东）和东盟各个国家分开统计
*/
@Component
public class Issue_G {
    private static final String inputDir = "F:\\IdeaProjects\\NLP2.0\\src\\test\\tmp\\Brunei";
    private static final String outputDir = "F:\\IdeaProjects\\NLP2.0\\src\\test\\tmp";
    private static final Logger logger = LoggerFactory.getLogger(Issue_G.class);
    private static Set<String> legalCountries = new HashSet<>();

    static {
        legalCountries.add("Brunei");
        legalCountries.add("Cambodia");
        legalCountries.add("Indonesia");
        legalCountries.add("Laos");
        legalCountries.add("Malaysia");
        legalCountries.add("Myanmar");
        legalCountries.add("Philippines");
        legalCountries.add("Singapore");
        legalCountries.add("Thailand");
        legalCountries.add("Vietnam");
        legalCountries.add("China");
    }


    public static void main(String[] args) throws IOException {
        Issue_G issueG = new Issue_G();
        issueG.solve(inputDir, "./test.json");
    }

    public String solve(String inputDir, String outputPath) throws IOException {
        Map<String, Map<String, Map<String, Integer>>> map = new HashMap<>();
        resolve(new File(inputDir), map);
        Map<String, List<AuthorInfo>> res = new HashMap<>();
        //国家 ：｛作者：｛学科：出现次数｝｝
        //key:国家
        for (Map.Entry<String, Map<String, Map<String, Integer>>> entry0 : map.entrySet()) {
            List<AuthorInfo> list = res.computeIfAbsent(entry0.getKey(), obj -> new LinkedList<>());
            //key: 作者
            for (Map.Entry<String, Map<String, Integer>> entry1 : entry0.getValue().entrySet()) {

//                authorInfo.setName(entry1.getKey());
                //key: 学科
                List<AuthorInfo.SubjectInfo> subjects = new ArrayList<>(entry1.getValue().size());
                AuthorInfo authorInfo = new AuthorInfo();
                list.add(authorInfo);
                int count = 0;
                for (Map.Entry<String, Integer> entry2 : entry1.getValue().entrySet()) {
                    count += entry2.getValue();
                    subjects.add(new AuthorInfo.SubjectInfo(entry2.getKey(), entry2.getValue()));
                }
                authorInfo.setName(entry1.getKey());
                authorInfo.setCount(count);
                authorInfo.setSubjects(subjects);
            }
        }
        Map<String, List<AuthorInfo>> filter = filter(res, 30);//仅需每个国家中发文量前30的作者
        Main.write(filter, outputPath);
        return outputDir + "\\issue_g.json";
    }

    private Map<String, List<AuthorInfo>> filter(Map<String, List<AuthorInfo>> res, int threshold) {
        Map<String, List<AuthorInfo>> ans = new HashMap<>();
        for (Map.Entry<String, List<AuthorInfo>> entry : res.entrySet()) {
            //main.quickSort(entry.getValue(), 0, entry.getValue().size() - 1);
            Collections.sort(entry.getValue());
            List<AuthorInfo> list = ans.computeIfAbsent(entry.getKey(), l -> new ArrayList<AuthorInfo>(30));
            for (int i = 0; i < entry.getValue().size() && i < threshold; i++) {
                list.add(entry.getValue().get(i));
            }
        }
        return ans;
    }

    private void resolve(File file, Map<String, Map<String, Map<String, Integer>>> map) throws IOException {
        File[] files = file.listFiles();
        for (File f : files) {
            if (f.isDirectory()) {
                resolve(f, map);
            } else {
                resoleFile(f, map);
            }
        }
    }

    private static Pattern pattern = Pattern.compile("\\[.*?\\]");

    private void resoleFile(File f, Map<String, Map<String, Map<String, Integer>>> map) throws IOException {
        String fn = f.getName();
        if (fn.contains("result") || fn.contains("issue") || fn.contains("statistic")) {
            return;
        }
        logger.info("Resolving {}", fn);
        List<Article> articles = JSONObject.parseArray(Main.read(f.getAbsolutePath()), Article.class);
        for (Article article : articles) {
            String[] authors = article.getC1();//作者-国家
            String[] sc = article.getSC(); //学科
            if (authors == null || sc == null) {
                continue;
            }
            Map<String, String> tmp = new HashMap<>();
            //构造作者 - 国家 map
            for (String author : authors) {
                // System.out.println(author);
                Matcher matcher = pattern.matcher(author);
                String authors_ = null;
                while (matcher.find()) {
                    authors_ = matcher.group();
                }
                if (authors_ == null) {
                    continue;
                }
                String[] strings = author.split(",");
                String country = strings[strings.length - 1];
                authors_ = authors_.substring(1, authors_.length() - 1);
                String[] as = authors_.split(";");
                for (String a : as) {
                    tmp.put(a.trim(), trim(country.trim()));
                }
            }
            for (Map.Entry<String, String> entry : tmp.entrySet()) {
                String author = entry.getKey();
                String country = entry.getValue();
                if (!legalCountries.contains(country)) {
                    continue;
                }
                Map<String, Map<String, Integer>> map1 = map.computeIfAbsent(country, m -> new HashMap<>());
                Map<String, Integer> map2 = map1.computeIfAbsent(author, m2 -> new HashMap<>());
                for (String s : sc) {
                    map2.put(s, map2.getOrDefault(s, 0) + 1);
                }
            }
        }
    }

    private String trim(String trim) {
        if (trim.charAt(trim.length() - 1) == '.') {
            trim =  trim.substring(0, trim.length() - 1);
        }
        if("Peoples R China".equals(trim)){
            trim ="China";
        }
        return trim;
    }

}
